package com.macro.mall.common.util;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.Inet4Address;
import java.net.UnknownHostException;
import java.util.Random;

/**
 * 雪花ID工具，生成workid及datacenterid
 * @author ouyang
 */
public class SnowflakeUtils {

    private static Logger logger = LoggerFactory.getLogger(SnowflakeUtils.class);

    /** 数据中心id所占长度 */
    private static final int DATA_LEN = 5;
    /** 机器id所占长度 */
    private static final int WORK_LEN = 5;

    /** 数据中心id最大值 31 */
    private static final int DATA_MAX_NUM = ~(-1 << DATA_LEN);
    /** 机器id最大值 31 */
    private static final int WORK_MAX_NUM = ~(-1 << WORK_LEN);
    /** 随机获取数据中心id的参数 32 */
    private static final int DATA_RANDOM = DATA_MAX_NUM + 1;
    /** 随机获取机器id的参数 32 */
    private static final int WORK_RANDOM = WORK_MAX_NUM + 1;

    private static Integer workId;
    private static Integer dataId;

    /**
     * 获取字符串s的字节数组，然后将数组的元素相加，对（max+1）取余
     */
    private static int getHostId(String s, int max){
        logger.info("ip=={}",s);
        byte[] bytes = s.getBytes();
        int sums = 0;
        for(int b : bytes){
            sums += b;
        }
        return sums % (max+1);
    }

    /**
     * 根据 host address 取余，发生异常就获取 0到31之间的随机数
     */
    private static int getWorkId(){
        if(null != workId){
            return workId;
        }
        try {
            workId =  getHostId(Inet4Address.getLocalHost().getHostAddress(), WORK_MAX_NUM);
            return workId;
        } catch (UnknownHostException e) {
            return new Random().nextInt(WORK_RANDOM);
        }
    }

    /**
     * 根据 host name 取余，发生异常就获取 0到31之间的随机数
     */
    private static int getDataId() {
        if(null != dataId){
            return dataId;
        }
        try {
            dataId = getHostId(Inet4Address.getLocalHost().getHostName(), DATA_MAX_NUM);
            return dataId;
        } catch (UnknownHostException e) {
            return new Random().nextInt(DATA_RANDOM);
        }
    }

    /**
     * 获取下一个可用的ID
     * @return
     */
    public static long getNextId(){
        Snowflake snowflake = IdUtil.getSnowflake(getWorkId(),getDataId() );
        return snowflake.nextId();
    }

    /**
     * 获取下一个可用的字符ID
     * @return
     */
    public static String getNextIdStr(){
        Snowflake snowflake = IdUtil.getSnowflake(getWorkId(),getDataId() );
        return snowflake.nextIdStr();
    }

    public static void main(String[] args) {
        System.out.println(SnowflakeUtils.getNextIdStr());
    }
}
